const Controller = require('../core/base_controller');

const fs = require('fs');
const path = require('path')
const sendToWormhole = require('stream-wormhole')
const uuid = require('uuid')
const assert = require('assert')
const xlsx = require('../lib/excel')

class AppController extends Controller {
    async upload() {
        const stream = await this.ctx.getFileStream();

        let fileName = `${uuid.v4()}.jpg`

        let filepath = path.join(this.app.config.baseDir, `static/file/${fileName}`);
        this.logger.warn('Saving %s to %s', stream.filename, filepath);
        try {
            await saveStream(stream, filepath);
        } catch (err) {
            await sendToWormhole(stream);
            throw err;
        }

        this.success(`/api/file/${fileName}`)
    }

    async uploadFile() {
        const stream = await this.ctx.getFileStream();

        let fileName = `${uuid.v4()}.jpg`

        let filepath = path.join(this.app.config.baseDir, `static/file/${fileName}`);
        this.logger.warn('Saving %s to %s', stream.filename, filepath);
        try {
            await saveStream(stream, filepath);
        } catch (err) {
            await sendToWormhole(stream);
            throw err;
        }

        this.success({
            url: `/api/file/${fileName}`,
            name: stream.filename,
            type: stream.mime,
        })
    }

    async download() {
        const { filename } = this.param
        let filepath = path.join(this.app.config.baseDir, `static/file/${filename}`);
        this.ctx.set('Content-Type', 'image/jpeg');
        this.ctx.body = fs.createReadStream(filepath);
    }

    async exportXls() {

        let { data, filename, columns } = this.param

        assert(data)
        assert(columns)

        data = JSON.parse(data)
        filename = filename
        columns = JSON.parse(columns)

        let buf = await xlsx.exportXls({
            data, filename, columns
        })

        this.ctx.attachment(`${filename}.xlsx`)
        this.ctx.set('content-type', 'application/oct-stream')

        this.ctx.body = buf
    }
}


function saveStream(stream, filepath) {
    return new Promise((resolve, reject) => {
        if (filepath.indexOf('/read-error-') > 0) {
            stream.once('readable', () => {
                const buf = stream.read(10240);
                console.log('read %d bytes', buf.length);
                setTimeout(() => {
                    reject(new Error('mock read error'));
                }, 1000);
            });
        } else {
            const ws = fs.createWriteStream(filepath);
            stream.pipe(ws);
            ws.on('error', reject);
            ws.on('finish', resolve);
        }
    });
}
module.exports = AppController;
